package com.sg;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SM4Utils {
    public String secretKey = "";
    public boolean hexString = true;

    public SM4Utils() {
    }

    private static final Log log = LogFactory.getLog(SM4Utils.class);

    public static boolean isNumber(String str) {
        // 采用正则表达式的方式来判断一个字符串是否为数字，这种方式判断面比较全
        // 可以判断正负、整数小数
        boolean isNumber = true;
        try {
            Double a = new Double(str);

        } catch (Exception e) {
            isNumber = false;
        }
        return isNumber;
    }

    //根据SAP规则对输出金额串进行处理，plainText为解密结果，若解密金额不为数值，则当0处理，适合计算金额使用
    public static String formatOutput(String plainText) {
        String formatString = plainText;
        //先作为数值型处理
        if (formatString != null) {
            if (formatString.endsWith(" ")) {
                // 若用空格结尾，则代表金额为正数，去掉空格即可
                formatString = formatString.trim();
            } else if (formatString.endsWith("-")) {
                // 若用空格结尾，则代表金额为正数，去掉空格即可
                formatString = "-" + formatString.substring(0, formatString.length() - 1);
            }

        }

        //若不为数值型，则处理为0
        if (!isNumber(formatString)) {
            formatString = "0";
        }

        return formatString;
    }

    //根据SAP规则对输出金额串进行处理，plainText为解密结果，若解密金额不为数值，则直接输出内容，适合导出使用。
    public static String formatOutputEXP(String plainText) {
        String formatString = plainText;
        if (formatString != null) {
            if (formatString.endsWith(" ")) {
                // 若用空格结尾，则代表金额为正数，去掉空格即可
                formatString = formatString.trim();
            } else if (formatString.endsWith("-")) {
                // 若用空格结尾，则代表金额为正数，去掉空格即可
                formatString = "-" + formatString.substring(0, formatString.length() - 1);
            }

        }

        //若不为数值型，则输出原来的文本
        if (!isNumber(formatString)) {
            formatString = plainText;
        }

        return formatString;
    }

    public String encryptData_ECB_HEX(String plainText) {
        try {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;
            ctx.mode = SM4.SM4_ENCRYPT;

            byte[] keyBytes;
            if (hexString) {
                keyBytes = Util.hexStringToBytes(secretKey);
            } else {
                keyBytes = secretKey.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_enc(ctx, keyBytes);
            byte[] encrypted = sm4.sm4_crypt_ecb(ctx, plainText.getBytes("GBK"));
            String cipherText = Util.bytesToHexString(encrypted);
            return cipherText;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public String decryptData_ECB_HEX(String cipherText, String secretKey, boolean hexString) {
        try {
            SM4_Context ctx = new SM4_Context();
            ctx.isPadding = true;
            ctx.mode = SM4.SM4_DECRYPT;

            byte[] keyBytes;
            if (hexString) {
                keyBytes = Util.hexStringToBytes(secretKey);
            } else {
                keyBytes = secretKey.getBytes();
            }

            SM4 sm4 = new SM4();
            sm4.sm4_setkey_dec(ctx, keyBytes);
            byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Util.hexStringToBytes(cipherText));
            return new String(decrypted, "GBK");
        } catch (Exception e) {
            log.error(e);
            return new String("0");
        }
    }

    public static void main(String[] args) throws IOException {

        String plainText = "955.00-";
        SM4Utils sm4 = new SM4Utils();
        sm4.secretKey = "50023031003E2B600000000000000000";
        sm4.hexString = true;

        System.out.println("ECB模式，打印密文为16进制字符串");
        String cipherText = sm4.encryptData_ECB_HEX(plainText);
        System.out.println("密文: " + cipherText);

        plainText = sm4.decryptData_ECB_HEX(cipherText, sm4.secretKey, sm4.hexString);
        System.out.println("明文: " + plainText);

        plainText = sm4.decryptData_ECB_HEX("22", sm4.secretKey, sm4.hexString);
        log.debug("解密: " + plainText);
        log.debug("转换为正常金额: " + formatOutput(plainText));
        log.debug("转换为导出: " + formatOutputEXP(plainText));

    }

    public static String decryptSample2(String cipherText) throws IOException {

        SM4Utils sm4 = new SM4Utils();
        sm4.secretKey = "50023031003E2B600000000000000000";
        sm4.hexString = true;

        String plainText = sm4.decryptData_ECB_HEX(cipherText, sm4.secretKey, sm4.hexString);
        log.debug("解密: " + plainText);
        log.debug("转换为正常金额: " + formatOutput(plainText));
        return formatOutput(plainText);
    }
}